// xxXX_ 标签名
const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`;
// xx:xx   <aa:xxx></aa:xxx>
const qnameCapture = `((?:${ncname}\\:)?${ncname})`;
// <xxx>
const startTagOpen = new RegExp(`^<${qnameCapture}`);
// </xxx>
const endTag = new RegExp(`<\\/${qnameCapture}[^>]*>`);

// xx="xx" xx='xx' xx
const attribute =
  /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/;

const startTagClose = /^\s*(\/?)>/;

export const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g;

function createAstElement(tagName, attrs) {
  return {
    tag: tagName,
    type: 1, // 元素1 文本3
    children: [],
    parent: null,
    attrs,
  };
}

export function parserHTML(html) {
  let root = null;
  let stack = [];
  // 将解析后的结果 组装成一个树结构 栈
  function start(tagName, attributes) {
    // console.log("tagName start", tagName, attributes);
    let parent = stack[stack.length - 1];
    let element = createAstElement(tagName, attributes);
    if (!root) {
      root = element;
    }
    // 当放入栈中时， 继续父亲是谁
    element.parent = parent;
    if (parent) {
      parent.children.push(element);
    }
    stack.push(element);
  }

  function chars(text) {
    text = text.replace(/\s/g, "");
    let parent = stack[stack.length - 1];
    if (text) {
      parent.children.push({
        type: 3,
        text,
      });
    }
  }

  function end(tagName) {
    // console.log("tagName end", tagName);

    let last = stack.pop();
    if (last.tag !== tagName) {
      throw new Error("标签有误");
    }
  }

  function advance(len) {
    html = html.substring(len);
  }

  function parseStartTag() {
    const start = html.match(startTagOpen);
    if (start) {
      const match = {
        tagName: start[1],
        attrs: [],
      };
      advance(start[0].length);

      let end;
      let attr;
      // 如果没有遇到标签结尾就不停的解析
      while (
        !(end = html.match(startTagClose)) &&
        (attr = html.match(attribute))
      ) {
        match.attrs.push({
          name: attr[1],
          value: attr[3] || attr[4] || attr[5],
        });
        advance(attr[0].length);
      }
      if (end) {
        advance(end[0].length);
      }
      return match;
    }

    // 不是开始标签
    return false;
  }

  // 看要解析的内容是否存在，如果存在就不停解析
  while (html) {
    let textEnd = html.indexOf("<"); // 当前解析的开头
    if (textEnd == 0) {
      // 解析开始标签
      const startTagMatch = parseStartTag();
      if (startTagMatch) {
        // console.log(startTagMatch);
        start(startTagMatch.tagName, startTagMatch.attrs);
        continue;
      }

      const endTagMatch = html.match(endTag);
      if (endTagMatch) {
        end(endTagMatch[1]);
        advance(endTagMatch[0].length);
        continue;
      }

      // const endTagMatch = parseEndTag();

      // if (endTagMatch) {
      // }
    }
    let text;
    if (textEnd > 0) {
      text = html.substring(0, textEnd);
    }
    if (text) {
      chars(text);
      advance(text.length);
    }
  }
  return root;
}